# coding=utf-8
# 学习单位  : 郑州大学
# @Author  : 铭同学
# @Time    : 2021/10/11 11:53
# @Software: PyCharm

# 线性回归实现二分类问题
import torch
# import torch.nn.functional as F #导入函数包

# 设置的数据为矩阵（2维）--这里还要注意torch.Tensor()和torch.tensor()的区别(传入的数据类型有差别)
x_data = torch.Tensor([[1.0],[2.0],[3.0]])
y_data = torch.Tensor([[0],[0],[1]])

# 设置分类器
class LogisticRegressionModel(torch.nn.Module):
    def __init__(self):
        super(LogisticRegressionModel, self).__init__()
        self.linear = torch.nn.Linear(1,1)

    def forward(self, x):
        y_pred = torch.sigmoid(self.linear(x))  # 此处利用sigmoid()函数将连续问题转换为2分类问题
        return y_pred
# 初始化分类器
model = LogisticRegressionModel()

# 初始化loss和优化器函数
criterion = torch.nn.BCELoss(reduction='sum')  # BCE--二分类交叉熵损失（专门处理分类问题的）
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)

# 开始训练轮次  forward、梯度清零、backward、update
for epoch in range(500):
    y_pred = model(x_data) # 预测--forward
    loss = criterion(y_pred, y_data) # 计算损失--forward
    print(f'训练轮次：{epoch}',f'本轮次损失：{loss.item()}')

    # the grad computer by .backward() will be accumulated. so before backward, remember set the grad to zero
    optimizer.zero_grad() # backward前梯度清零
    loss.backward() # backward自动计算梯度
    optimizer.step() # update 参数，对w（权重）和b（偏置）进行更新


print('w = ', model.linear.weight.item())
print('b = ', model.linear.bias.item())


# 用数据进行测试训练结果
x_test = torch.tensor([[4.0]])
y_test = model(x_test)
print(f'y_pred = {y_test.data.item()}')


